package nc.impl.ntb;

import java.util.Hashtable;
import nc.vo.bd.access.AccessorManager;
import nc.vo.bd.access.BddataVO;
import nc.vo.bd.access.IBDAccessor;

public class BDAccessorCache {

	private class BDAccessorObject {
		private IBDAccessor accessor;
		private String pk_uapData;
		private String pk_corp;
		private String ext_Str;
		private Hashtable<String, BddataVO> hmCode2VO = new Hashtable<String, BddataVO>();
		
		public BDAccessorObject(String arg1) {
			pk_uapData = arg1;
		}
		public BDAccessorObject(String arg1, String arg2) {
			pk_uapData = arg1;
			pk_corp = arg2;
		}
		public BDAccessorObject(String arg1, String arg3, String arg2) {
			pk_uapData = arg1;
			pk_corp = arg2;
			ext_Str = arg3;
		}
//		private void initCode2VoMap() {
//			if (hmCode2VO != null)
//				return;
//			hmCode2VO = new Hashtable<String, BddataVO>();
//			BddataVO[] vos = getBDAccessor().getAllDocs();
//			if (vos != null) {
//				for (int i=0; i<vos.length; i++)
//					hmCode2VO.put(vos[i].getCode(), vos[i]);
//			}
//		}
		protected IBDAccessor getBDAccessor() {
			if (accessor == null) {
				if (pk_corp == null) {
					accessor = AccessorManager.getAccessor(pk_uapData);
				}
				else if (ext_Str == null) {
					accessor = AccessorManager.getAccessor(pk_uapData, pk_corp);
				}
				else {
					accessor = AccessorManager.getAccessor(pk_uapData, ext_Str, pk_corp);
				}
			}
			return accessor;
		}
		protected BddataVO getBddataVOByCode(String code) {
//			if (hmCode2VO == null) {
//				initCode2VoMap();
//			}
//			BddataVO vo = hmCode2VO.get(code);
			if (!hmCode2VO.containsKey(code)) {
				BddataVO vo = getBDAccessor().getDocByCode(code);
				if(vo!=null){
				   hmCode2VO.put(code, vo);
				}
				return vo;
			}
			else {
				return hmCode2VO.get(code);
			}
		}
		protected void clear() {
			if (hmCode2VO != null)
				hmCode2VO.clear();
			accessor = null;
		}
	}
	
	private final static String null_key = "null_value";
	private Hashtable<String, Hashtable<String, BDAccessorObject>> map;
	public BDAccessorCache() {
		map = new Hashtable<String, Hashtable<String, BDAccessorObject>>();
	}
	public void clear() {
		if (map.isEmpty())
			return;
		for (Hashtable<String, BDAccessorObject> hm : map.values()) {
			if (hm.isEmpty())
				continue;
			for (BDAccessorObject bdo : hm.values()) {
				bdo.clear();
			}
			hm.clear();
		}
		map.clear();
	}
	private BDAccessorObject getBDAccessorObject(String arg1, String arg3, String arg2) {
		String uapKey = arg3==null ? arg1 : arg1+arg3;
		Hashtable<String, BDAccessorObject> hm = map.get(uapKey);
		if (hm == null) {
			hm = new Hashtable<String, BDAccessorObject>();
			map.put(uapKey, hm);
		}
		String key = arg2==null ? null_key : arg2;
		BDAccessorObject acc = hm.get(key);
		if (acc == null) {
			acc = new BDAccessorObject(arg1, arg3, arg2);
			hm.put(key, acc);
		}
		return acc;
	}
	public IBDAccessor getBDAccessor(String arg1) {
		return getBDAccessor(arg1, null, null);
	}
	public IBDAccessor getBDAccessor(String arg1, String arg2) {
		return getBDAccessor(arg1, null, arg2);
	}
	public IBDAccessor getBDAccessor(String arg1, String arg3, String arg2) {
		BDAccessorObject acc = getBDAccessorObject(arg1, arg3, arg2);
		return acc==null ? null : acc.getBDAccessor();
	}
	public BddataVO getBddataVOByCode(String arg1, String code) {
		return getBddataVOByCode(arg1, null, null, code);
	}
	public BddataVO getBddataVOByCode(String arg1, String arg2, String code) {
		return getBddataVOByCode(arg1, null, arg2, code);
	}
	public BddataVO getBddataVOByCode(String arg1, String arg3, String arg2, String code) {
		BDAccessorObject acc = getBDAccessorObject(arg1, arg3, arg2);
		return acc==null ? null : acc.getBddataVOByCode(code);
	}
}
